package com.yunzhi.net.callback;

import android.content.Context;

import androidx.annotation.NonNull;

import com.google.gson.JsonParseException;
import com.yunzhi.net.entity.BaseResponse;
import com.yunzhi.net.enumerate.AppStateCode;
import com.yunzhi.net.enumerate.ExceptionReason;

import org.json.JSONException;
import java.net.UnknownHostException;
import java.text.ParseException;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import retrofit2.HttpException;

/**
 * Author by Mr.Meng
 * created 2019/5/15
 *
 * @desc 网络状态的封装类，子类初始化该类后，必须重写onSuccess(response)方法，可以选择性的重写onFailing(response)
 * 方法，如果子类使用super方法，那么会按照统一的方法进行{@link ToastUtils}，如果不使用则根据返回的response自行进行操作，如果选择重写onError(Throwable e)
 * 方法，如果子类使用super方法，那么会按照统一的方法进行{@link ToastUtils}，如果不使用则不会{@link ToastUtils}，但是您可以做自己的操作
 */
public abstract class BaseObserver<T extends BaseResponse> implements Observer<T> {

    protected Context context;
    private boolean isShowLoad;//后期衍生加载框


    public BaseObserver(@NonNull Context context, boolean isShowLoad) {
        this.context = context;
        this.isShowLoad = isShowLoad;
    }

    @Override
    public void onSubscribe(Disposable d) {
        //开始  可以封装dialog请求框
        disposable(d);
    }

    @Override
    public void onNext(T t) {
        //逻辑错误
        int code = t.getCode();
        switch (code) {
            case 0:
                onSuccess(t);
                break;
            case 1:
                onLogicError(AppStateCode.APP_NORMAL_ERROR_CODE, t.getMessage());
                break;
            case 2:
                onLogicError(AppStateCode.APP_DIALOG_ERROR_CODE,  t.getMessage());
                break;
            case 1000:
                onLogicError(AppStateCode.APP_ACCESS_TOKEN_ERROR_CODE,  t.getMessage());
                break;
            case 1001:
                onLogicError(AppStateCode.APP_ACCESS_TOKEN_INVALIDATION_CODE,  t.getMessage());
                break;
            case 1002:
                onLogicError(AppStateCode.APP_USER_OFF_LINE_CODE,  t.getMessage());
                break;
            case 1003:
                onLogicError(AppStateCode.APP_USER_NEED_LOGIN_CODE,  t.getMessage());
                break;
            case 1004:
                onLogicError(AppStateCode.APP_USER_NEED_BIND_PHONE_CODE,  t.getMessage());
                break;
            case 1005:
                onLogicError(AppStateCode.APP_USER_NOT_MONEY_CODE,  t.getMessage());
                break;
            case 1006:
                onLogicError(AppStateCode.APP_USER_NEED_REAL_NAME_AUTH_CODE,  t.getMessage());
                break;
            case 1007:
                onLogicError(AppStateCode.APP_USER_MESSAGE_LIMIT_CODE,  t.getMessage());
                break;
            case 1008:
                onLogicError(AppStateCode.APP_USER_FEE_DEDUCTION_ERROR_CODE,  t.getMessage());
                break;
            default:
                onError(code,  t.getMessage());
                break;
        }
    }

    @Override
    public void onError(Throwable e) {
        //网络错误
        if (e instanceof HttpException) {
            HttpException exception = (HttpException) e;
            onError(exception.code(), onHttpError(exception.code()));
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException) {
            onError(600, onHttpError(600));
        } else if (e instanceof UnknownHostException) {
            UnknownHostException ioException = (UnknownHostException) e;
            onError(602, onHttpError(602));
        } else {
            onError(601, onHttpError(601));
        }
        e.printStackTrace();


    }

    @Override
    public void onComplete() {
        //结束 可以封装dialog请求框关闭
    }


    public abstract void disposable(Disposable disposable);

    public abstract void onSuccess(T entity);

    public abstract void onError(int code, String msg);


    /**
     * 业务错误
     */
    protected void onLogicError(AppStateCode error, String msg) {

    }

    /**
     * 网络错误
     */
    private String onHttpError(int errorCode) {
        String msg = "";
        switch (errorCode) {
            case 400:
                msg = ExceptionReason.BAD_REQUEST.getValue();
                break;
            case 401:
                msg = ExceptionReason.UNAUTHORIZED.getValue();
                break;
            case 403:
                msg = ExceptionReason.FORBIDDEN.getValue();
                break;

            case 404:
                msg = ExceptionReason.NOT_FOUND.getValue();
                break;
            case 406:
                msg = ExceptionReason.FAIL_QUEST.getValue();
                break;
            case 408:
                msg = ExceptionReason.CONNECT_TIMEOUT.getValue();
                break;

            case 500:
                msg = ExceptionReason.INTERNAL_SERVER_ERROR.getValue();
                break;

            case 502:
                msg = ExceptionReason.BAD_GATEWAY.getValue();
                break;

            case 504:
                msg = ExceptionReason.GATEWAY_TIMEOUT.getValue();
                break;
            case 600:
                msg = ExceptionReason.PARSE_ERROR.getValue();
                break;
            case 602:
                msg = ExceptionReason.UNKNOWN_HOST_EXCEPTION_ERROR.getValue();
                break;
            default:
                msg = ExceptionReason.UNKNOWN_ERROR.getValue();
                break;
        }

        return msg;
    }


}
